package com.plan.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plan.demo.config.AjaxResult;
import com.plan.demo.entity.Duty;
import com.plan.demo.entity.User;
import com.plan.demo.entity.Work;
import com.plan.demo.service.DutyService;
import com.plan.demo.service.UserService;
import com.plan.demo.service.WorkService;
import com.plan.demo.vo.CountPeopleVo;
import com.plan.demo.vo.PlanVo;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jh
 */
@RestController
@RequestMapping("/plan")
public class PlanController {

    @Resource
    UserService userService;
    @Resource
    WorkService workService;
    @Resource
    DutyService dutyService;

    /**
     * 根据文件后缀名类型获取对应的工作簿对象
     * //     * @param inputStream 读取文件的输入流
     *
     * @return 包含文件数据的工作簿对象
     * @throws IOException
     */
    @PostMapping("import")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult getWorkbook(@RequestBody MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
/*    public AjaxResult getWorkbook() throws IOException {
        File file = new File("C:\\Users\\Administrator\\Desktop\\磐安2021年8月排班表0731.xlsx");
        FileInputStream inputStream = new FileInputStream(file);*/
        userService.clear();
        workService.clear();
        dutyService.clear();
        Workbook workbook = null;
        workbook = new XSSFWorkbook(inputStream);
        Sheet sheet = workbook.getSheet("磐安2021排班");
        // 获取上班用户信息数据
        Row userRow = sheet.getRow(5);
        Map<Integer, Long> map = new HashMap();
        for (int i = 2; i < 10; i++) {
            User user = new User();
            String name = userRow.getCell(i).toString();
            user.setPlanNumber(0);
            user.setUserName(name);
            user.setCreateTime(new Date());
            userService.save(user);
            map.put(i, user.getId());
        }

        ArrayList<Work> workList = new ArrayList<>();
        for (int i = 6; i < 300; i++) {
            // 获取上班信息数据
            Row row = sheet.getRow(i);
            Row rowTop = sheet.getRow(i - 1);
            Row rowNext = sheet.getRow(i + 1);
            String cell = row.getCell(0).toString();
            if (StringUtils.isEmpty(cell)) {
                break;
            }
            String day = this.initDate(row.getCell(0).toString());
            this.initDuty(day);
            for (int j = 2; j < 10; j++) {
                Work work = new Work();
                if (ObjectUtils.isEmpty(row)) {
                    break;
                }
                String value = row.getCell(j).toString();
                if ("1.0".equals(value)) {
                    work.setCreateTime(new Date());

                    work.setWorkDay(day);
                    work.setUserId(map.get(j));
                    // 判断是否为上班第一天或者下班最后一天
                    if (!("1.0".equals(rowTop.getCell(j).toString()))) {
                        work.setIsFirst(1);
                    }
                    if (!("1.0".equals(rowNext.getCell(j).toString()))) {
                        work.setIsLast(1);
                    }
                    workService.save(work);
                }
            }
        }
        return AjaxResult.success("导入成功!");
    }

    @GetMapping("")
    public AjaxResult getPlan() {
        List<PlanVo> list = dutyService.getPlan();
        return AjaxResult.success(list);
    }

    /**
     * 排值班表
     */
    @GetMapping("schedule")
    public AjaxResult doPlan() throws Exception {
        LambdaQueryWrapper<Duty> order = new LambdaQueryWrapper<Duty>().orderByAsc(Duty::getDay, Duty::getType);
        List<Duty> dutyList = dutyService.list(order);
        for (int i = 0; i < dutyList.size(); i++) {
            Duty duty = dutyList.get(i);
            // 值白班排班
            if (1 == duty.getType()) {
                // 1.不是第一天上班的
                LambdaQueryWrapper<Work> workWrapper = new LambdaQueryWrapper<Work>()
                        .eq(Work::getWorkDay, duty.getDay())
                        .eq(Work::getIsFirst, 0);
                List<Work> workList = workService.list(workWrapper);
                // 找不到的话先跳过这一天,人工手动排
                if (workList.size() > 0) {
                    List<Long> userIds = workList.stream().map(x -> x.getUserId()).collect(Collectors.toList());
                    String day = duty.getDay();
                    //前一天
                    String lastDay = this.getLastDay(day);
                    // 找到前一天值白班和夜班的人,除去这两人
                    LambdaQueryWrapper<Duty> dutyWrapper = new LambdaQueryWrapper<Duty>().eq(Duty::getDay, lastDay);
                    List<Duty> list = dutyService.list(dutyWrapper);
                    List<Long> wipeUsers = new ArrayList<>();
                    if (list.size() > 0) {
                        wipeUsers = list.stream().map(x -> x.getUserId()).collect(Collectors.toList());
                    }
                    List<Long> users = this.initUsers(userIds, wipeUsers);
                    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                            .in(users.size() > 0, User::getId, users)
                            .eq(users.size() == 0, User::getDeleted, 1)
                            .orderByAsc(User::getPlanNumber, User::getDayNumber);
                    List<User> userList = userService.list(wrapper);
                    // 找不到的话先跳过这一天,人工手动排
                    if (userList.size() > 0) {
                        User user = userList.get(0);
                        duty.setUserId(user.getId());
                        user.setDayNumber(user.getDayNumber() + 1);
                        user.setPlanNumber(user.getPlanNumber() + 1);
                        userService.updateById(user);
                        dutyService.updateById(duty);
                    }
                }
            }

            // 值晚班排班
            if (2 == duty.getType()) {
                // 1.不是最后一天下班的
                LambdaQueryWrapper<Work> workWrapper = new LambdaQueryWrapper<Work>()
                        .eq(Work::getWorkDay, duty.getDay())
                        .eq(Work::getIsLast, 0);
                List<Work> workList = workService.list(workWrapper);
                // 找不到的话先跳过这一天,人工手动排
                if (workList.size() > 0) {
                    List<Long> userIds = workList.stream().map(x -> x.getUserId()).collect(Collectors.toList());
                    String day = duty.getDay();
                    //前一天
                    String lastDay = this.getLastDay(day);
                    // 找到前一天值白班和夜班的人,除去这两人
                    LambdaQueryWrapper<Duty> dutyWrapper = new LambdaQueryWrapper<Duty>().eq(Duty::getDay, lastDay).eq(Duty::getType, 2);
                    List<Duty> list = dutyService.list(dutyWrapper);
                    // 找到当天值白班,除去这个人
                    LambdaQueryWrapper<Duty> dutyNowWrapper = new LambdaQueryWrapper<Duty>().eq(Duty::getDay, day).eq(Duty::getType, 1);
                    Duty dutyDay = dutyService.getOne(dutyNowWrapper);
                    list.add(dutyDay);
                    List<Long> wipeUsers = new ArrayList<>();
                    if (list.size() > 0) {
                        wipeUsers = list.stream().map(x -> x.getUserId()).collect(Collectors.toList());
                    }
                    List<Long> users = this.initUsers(userIds, wipeUsers);
                    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                            .in(users.size() > 0, User::getId, users)
                            .eq(users.size() == 0, User::getDeleted, 1)
                            .orderByAsc(User::getPlanNumber, User::getNightNumber);
                    List<User> userList = userService.list(wrapper);
                    // 找不到的话先跳过这一天,人工手动排
                    if (userList.size() > 0) {
                        User user = userList.get(0);
                        duty.setUserId(user.getId());
                        user.setDayNumber(user.getDayNumber() + 1);
                        user.setPlanNumber(user.getPlanNumber() + 1);
                        userService.updateById(user);
                        dutyService.updateById(duty);
                    }
                }
            }
        }
        return AjaxResult.success("排班成功!");
    }

    /**
     * 统计总数
     */
    @GetMapping("count/all")
    public AjaxResult countPeopleAll() {
        List<CountPeopleVo> list = dutyService.getCountPeopleAll();
        return AjaxResult.success(list);
    }

    /**
     * 根据日夜班统计总数
     */
    @GetMapping("count/people")
    public AjaxResult countPeople() {
        List<CountPeopleVo> list = dutyService.getCountPeople();
        return AjaxResult.success(list);
    }

    @GetMapping("clear")
    public AjaxResult clear(){
        userService.clear();
        workService.clear();
        dutyService.clear();
        return AjaxResult.success("重置成功");
    }

    /**
     * 初始化时间格式
     */
    private String initDate(String date) {
        String[] time = date.split("-");
        String day = time[0];
        String month = "";
        String year = time[2];
        switch (time[1]) {
            case "一月":
                month = "01";
                break;
            case "二月":
                month = "02";
                break;
            case "三月":
                month = "03";
                break;
            case "四月":
                month = "04";
                break;
            case "五月":
                month = "05";
                break;
            case "六月":
                month = "06";
                break;
            case "七月":
                month = "07";
                break;
            case "八月":
                month = "08";
                break;
            case "九月":
                month = "09";
                break;
            case "十月":
                month = "10";
                break;
            case "十一月":
                month = "11";
                break;
            case "十二月":
                month = "12";
                break;
            default:
        }
        return year + "-" + month + "-" + day;
    }

    /**
     * 初始化新增值班日期信息
     */
    private void initDuty(String day) {
        Duty duty = new Duty();
        duty.setCreateTime(new Date());
        duty.setDay(day);
        duty.setType(1);
        dutyService.save(duty);
        duty.setId(null);
        duty.setType(2);
        dutyService.save(duty);
    }

    /**
     * 将前一天的值班人员从今天上班人员集合中去除
     */
    private List<Long> initUsers(List<Long> userIds, List<Long> wipeUsers) {
        List<Long> result = new ArrayList<Long>();
        for (Long id : userIds) {
            //判断是否包含
            if (!wipeUsers.contains(id)) {
                result.add(id);
            }
        }
        return result;
    }

    private String getLastDay(String day) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(day);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, -1); //减1天
        return simpleDateFormat.format(cal.getTime());
    }


}
